package s

import (
	"bufio"
	"log"
	"os"
	"strings"
)

var (
	INSERT = 0x10011100119
)

type InsertFunc func(ex EStr) Str

/*

Edit(s.IN, 'xxx', 'xxxend', func(ex ExStr) Str{})
*/
func (self Str) Edit(limit ...any) Str {
	// Not := false
	In := false
	// Range := ExtractStr{Str: "", Start: -1, End: -1}
	content := ""
	sub := self.Copy()
	Pre := ""
	End := ""
	// ExStr := ExtractStr{
	// 	Str:   "",
	// 	Start: -1,
	// 	End:   -1,
	// }
	// loc := -1
	for _, l := range limit {
		if i, ok := l.(int); ok {
			if i == IN {
				In = true
			}

		} else if limitRange, ok := l.(EStr); ok {
			if In {
				In = false
				sub = sub[:limitRange.Start] + Str(content) + sub[limitRange.End:]

			} else {
				log.Fatal("InsertStr must： IN xxExStr  ")
			}
		} else if limitStr, ok := l.(string); ok {
			// end := limitPre
			if In {
				if Pre != "" {
					End = limitStr
				} else {
					Pre = limitStr
				}
			}
		} else if limitFunc, ok := l.(func(ex EStr) Str); ok {
			if In {
				if Pre != "" {
					if End == "" {
						End = Pre
					}
					// pp := sub.Copy()
					ss := []string{}
					for _, ex := range sub.Extract(Pre, End) {
						// ex.ANSIBlue().Println()
						// sub[ex.End:].ANSIYellow().Println("test end:")
						ss = append(ss, sub[:ex.Start].String(), string(limitFunc(ex)), sub[ex.Next:].String())
					}
					sub = Str(strings.Join(ss, ""))
				}
			}
		}
	}
	return sub
}

func (self Str) Insert(content string, condss ...any) Str {
	last := false
	after := false
	// before := false
	for _, conds := range condss {

		if condsStr, ok := conds.(string); ok {
			c := self.Index(condsStr, last)
			if after {
				c += len(condsStr)
			}
			return self[:c] + Str(content) + self[c:]
		} else if condInt, ok := conds.(int); ok {
			if condInt == LAST {
				last = true
			} else if condInt == AFTER {
				after = true
			} else if condInt == BEFORE {
				// before = true
			} else {
				return self[:condInt] + Str(content) + self[condInt:]

			}
		} else if condEx, ok := conds.(EStr); ok {
			return self[:condEx.Start] + Str(content) + self[condEx.End:]
		} else {
			log.Fatal("only support int/string/EStr")
		}

	}
	return Str("")
}

func (self Str) AsInput() Str {
	self.Print()
	reader := bufio.NewReader(os.Stdin)
	line, _, err := reader.ReadLine()
	if err != nil {
		SafePush(&ErrStack, err)
		return ""
	}
	return Str(line)
	// os.Stdin
}
